package com.tianluo.tianluobookstore.service;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

@Component
public class RedisLockTemplate {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 加锁并执行给定的操作，返回结果
     *
     * @param lockKey 锁的键
     * @param timeout 锁的自动释放时间（秒）
     * @param action 需要执行的操作
     * @param <T>    操作的返回类型
     * @return 执行结果
     */
    public <T> T executeWithLock(String lockKey, long timeout, Callable<T> action) {
        RLock lock = redissonClient.getLock(lockKey);
        boolean isLock = false;

        try {
            // 尝试获取锁，最大等待时间1秒，锁自动释放时间为timeout秒
            isLock = lock.tryLock(1, timeout, TimeUnit.SECONDS);
            if (isLock) {
                try {
                    // 执行传入的操作并返回结果
                    return action.call();
                } finally {
                    // 检查是否持有锁再释放
                    if (lock.isHeldByCurrentThread()) {
                        lock.unlock();
                    }
                }
            } else {
                System.out.println("未能获取锁，稍后重试");
                return null; // 或者抛出异常
            }
        } catch (InterruptedException e) {
            // 处理异常，恢复线程中断状态
            Thread.currentThread().interrupt();
            System.out.println("获取锁时被中断");
            return null; // 或者抛出异常
        } catch (Exception e) {
            // 处理其他异常
            System.out.println("执行操作时发生异常: " + e.getMessage());
            return null; // 或者抛出异常
        }
    }
}
